<?php
/**
 * Nweb Framework
 *
 * This script is protected by copyright. It's use, copying, modification
 * and distribution without written consent of the author is prohibited.
 *
 * @category    source
 * @package     pl.nweb.framework.http
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @license     http://www.gnu.org/licenses/lgpl-3.0.txt  GNU Lesser General Public
 * @version     3.0 $Id: client.php 452 2011-12-07 12:04:19Z krzysztof.kardasz $
 * @link        http://code.google.com/p/nweb-framework/
 * @link        http://framework.nweb.pl
 */

namespace pl\nweb\framework\http;

/**
 * Klient HTTP
 *
 * @category    source
 * @package     pl.nweb.framework.http
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @version     3.0 $Id: client.php 452 2011-12-07 12:04:19Z krzysztof.kardasz $
 */
class Client
{
    /**
     * Adapter klienta HTTP
     *
     * @var \pl\nweb\framework\http\client\adapter
     */
    private $_adapter = null;

    /**
     * Obiekt odpowiedzi
     *
     * @var \pl\nweb\framework\http\Response
     */
    private $_response = null;

    /**
     * Obiekt żądania
     *
     * @var \pl\nweb\framework\http\Request
     */
    private $_request = null;

    /**
     * Definiuje adapter klienta
     *
     * @param  \pl\nweb\framework\http\client\Adapter $adapter adapter klienta
     * @return \pl\nweb\framework\http\Client
     */
    public function setAdapter(client\Adapter $adapter)
    {
        $this->_adapter = $adapter;
        return $this;
    }

    /**
     * Zwraca adapter klienta
     *
     * @return \pl\nweb\framework\http\client\Adapter
     */
    public function getAdapter()
    {
        if(null === $this->_adapter) {
            $this->_adapter = new client\adapter\Curl();
        }
        return $this->_adapter;
    }

    /**
     * Definiuje konfigurację
     *
     * @param  array|string $key klucz/tablica wartości
     * @param  mixed $value wartość dla klucza
     * @return \pl\nweb\framework\http\Client
     */
    public function setConfig($key, $value = null)
    {
        $this->getAdapter()->setConfig($key, $value);
        return $this;
    }

    /**
     * Zwraca konfigurację / wartości konfiguracji
     *
     * @param  null|string $key klucz
     * @param  null|mixed $default domyślna wartość
     * @return \pl\nweb\framework\http\Client
     */
    public function getConfig($key = null, $default = null)
    {
        return $this->getAdapter()->getConfig($key, $default);
    }

    /**
     * Definiuje metodę
     *
     * @param string $method metoda
     * @return \pl\nweb\framework\http\Client
     */
    public function setMethod($method)
    {
        $this->getAdapter()->setMethod(strtoupper($method));
        return $this;
    }

    /**
     * Definiuje adres url
     *
     * @param string $uri adres
     * @return \pl\nweb\framework\http\Client
     * @throws Exception
     */
    public function setUri($uri)
    {
        $this->getAdapter()->setUri($uri);
        return $this;
    }

    /**
     * Definiuje treść żądania
     *
     * @param string $body treść
     * @return \pl\nweb\framework\http\Client
     */
    public function setBody($body)
    {
        $this->getAdapter()->setBody($body);
        return $this;
    }

    /**
     * Definiuje nagłówek
     *
     * @param string|array $name nazwa nagłówka lub tablica nagłówków
     * @param mixed|null $value wartość nagłówka
     * @return \pl\nweb\framework\http\Client
     */
    public function setHeader($name, $value = null)
    {
        $this->getAdapter()->setHeader($name, $value);
        return $this;
    }

    /**
     * Definiuje parametr GET
     *
     * @param string|array $key klucz lub tablica parametrów
     * @param mixed|null $value wartość
     * @return \pl\nweb\framework\http\Client
     */
    public function setParamGet($key, $value = null)
    {
        $this->getAdapter()->setParamGet($key, $key);
        return $this;
    }

    /**
     * Definiuje parametr POST
     *
     * @param string|array $key klucz lub tablica parametrów
     * @param mixed|null $value wartość
     * @return \pl\nweb\framework\http\Client
     */
    public function setParamPost($key, $value = null)
    {
        $this->getAdapter()->setParamPost($key, $value);
        return $this;
    }

    /**
     * Wysyła żądanie
     *
     * @param  string|null $method metoda
     * @return \pl\nweb\framework\http\Client
     * @throws \pl\nweb\framework\http\client\adapter\Exception
     */
    public function request()
    {
        $this->_response = $this->getAdapter()->request();
        $this->_request  = $this->getAdapter()->getRequest();
        return $this;
    }

    /**
     * Zwraca odpowiedź
     *
     * @return \pl\nweb\framework\http\Response
     * @throws \pl\nweb\framework\http\client\Exception
     */
    public function getResponse()
    {
        if(null === $this->_response) {
            throw new client\Exception ('Request is not sent', 1301, $this);
        }
        return $this->_response;
    }

    /**
     * Zwraca żądanie
     *
     * @return \pl\nweb\framework\http\Request
     * @throws \pl\nweb\framework\http\client\Exception
     */
    public function getRequest()
    {
        if(null === $this->_request) {
            throw new client\Exception ('Request is not sent', 1302, $this);
        }
        return $this->_request;
    }
}
